package meshGrammar;

import java.util.ArrayList;



public class RuleExtrude extends Rule {
	public  Mesh replace(Mesh mesh){
		mesh.construct();
		ArrayList<MeshNode>newNodes=new  ArrayList<MeshNode>();
		for (int i=0;i<mesh.getNNodes();i++){
			MeshNode node=mesh.getNode(i);
			//Vec3D v=node.getNormal();
			Vec3D v=node.getNormalUnscaled();
			//System.out.println("eF: "+this.extrudeFactorNode);
			//extrudeFactorNode=0.2f;
			//v.mult(this.extrudeFactorNode);
			
			MeshNode copyNode=new MeshNode(node);
			copyNode.add(v);
			newNodes.add(copyNode);
		}
		boolean[]holes=new boolean[mesh.getNFaces()];
		for (int i=0;i<holes.length;i++){
			if (i%3==0){
				holes[i]=true;
			}
		}
		
		ArrayList<MeshFace>newFaces=new  ArrayList<MeshFace>();
		for (int i=0;i<holes.length;i++){
			if (!holes[i]){
				MeshFace face=mesh.getFace(i);
				MeshFace newFace1=new MeshFace();
				MeshFace newFace2=new MeshFace();
				for (int j=0;j<face.getNNodes();j++){
					newFace1.addNode(mesh.getNode(face.getNode(j).getId()));
					newFace2.addNode(newNodes.get(face.getNode(j).getId()));
				}
				newFaces.add(newFace1);
				newFaces.add(newFace2);
				newFace1.inverse();
			}
		}
		
		
		
		for (int i=0;i<mesh.getNEdges();i++){
			MeshEdge edge1=mesh.getEdge(i);
			MeshFace face11=edge1.getFace1();
			MeshFace face12=edge1.getFace2();
			if (face11!=null&&face12!=null){
			if (holes[face11.getId()]!=holes[face12.getId()]){
				
				MeshNode n1=edge1.getNode1();
				MeshNode n2=edge1.getNode2();
				MeshNode n3=newNodes.get(n2.getId());
				MeshNode n4=newNodes.get(n1.getId());
				
				MeshFace newFace=new MeshFace(n4,n3,n2,n1);
				if (!holes[face11.getId()]){
					 newFace=new MeshFace(n1,n2,n3,n4);
				}
				else{
					 newFace=new MeshFace(n4,n3,n2,n1);
				}
				newFaces.add(newFace);
			}
			}
		}
		
		Mesh newMesh=new Mesh();
		newMesh.nodes=newNodes;
		newMesh.nodes.addAll(mesh.nodes);
		newMesh.faces=newFaces;
		newMesh.construct();
		//newMesh.collectEdges();
		newMesh.removeUnusedNodes();
		newMesh.construct();
		//System.out.println("nFaces:"+newMesh.faces.size());
		//mesh.
		return newMesh;
	}
}
